home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_geomview.idb / usr / freeware / catman / p_man / cat3 / lisp.Z / lisp
Encoding:
Text File  |  1999-01-26  |  21.8 KB  |  595 lines

  1.  
  2.  
  3.  
  4.      lllliiiisssspppp((((3333))))           GGGGeeeeoooommmmeeeettttrrrryyyy    CCCCeeeennnntttteeeerrrr ((((OOOOcccctttt 22222222 1111999999992222))))           lllliiiisssspppp((((3333))))
  5.  
  6.  
  7.  
  8.      NNNNAAAAMMMMEEEE
  9.       geomview lisp    interpreter
  10.  
  11.      NNNNOOOOTTTTEEEE
  12.       This document    describes the geomview 1.3 lisp    interpreter.
  13.       This version is incompatible with previous versions in
  14.       several ways.     Since the previous one    was used mostly    just
  15.       by Geometry Center staff, I am not going to write a document
  16.       detailing the    changes.  The geomview lisp interpreter    is not
  17.       very well documented in general because I am strongly
  18.       considering phasing it out and replacing it with a real lisp
  19.       interpreter in a future version of geomview.    If you have
  20.       any questions    about the current version or how to convert
  21.       programs from    an older version please    contact    me directly [
  22.       mbp@geom.umn.edu ].
  23.  
  24.  
  25.      SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
  26.       #include "lisp.h"
  27.  
  28.       void        LInit();
  29.       Lake *     LakeDefine(FILE *streamin, FILE *streamout, void *river);
  30.       void        LakeFree(Lake *lake);
  31.       LObject *     LNew(LType *type, LCell *cell);
  32.       LObject *     LRefIncr(LObject *obj);
  33.       void        LRefDecr(LObject *obj);
  34.       void        LWrite(FILE    *fp, LObject *obj);
  35.       void        LFree(LObject *obj);
  36.       LObject   *     LCopy(LObject *obj);
  37.       LObject *     LSexpr(Lake *lake);
  38.       LObject *     LEval(LObject *obj);
  39.       LObject * LEvalSexpr(Lake *lake);
  40.       LList        *     LListNew();
  41.       LList        *     LListAppend(LList *list, LObject *obj);
  42.       void        LListFree(LList *list);
  43.       LList    *     LListCopy(LList *list);
  44.       LObject *     LListEntry(LList *list, int n);
  45.       int        LListLength(LList *list);
  46.       int        LParseArgs(char *name, Lake    *lake, LList *args, ...);
  47.       int        LDefun(char    *name, LObjectFunc func, char *help);
  48.       void        LListWrite(FILE *fp, LList *list);
  49.       LInterest *     LInterestList(char *funcname);
  50.       LObject * LEvalFunc(char *name, ...);
  51.       int        LArgClassValid(LType *type);
  52.       void        LHelpDef(char *key,    char *message);
  53.  
  54.       LDEFINE(name,    ltype, doc)
  55.  
  56.       LDECLARE((name,  LBEGIN,
  57.          ...,
  58.          LEND));
  59.  
  60.  
  61.  
  62.  
  63.      Page 1                        (printed 12/22/98)
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.      lllliiiisssspppp((((3333))))           GGGGeeeeoooommmmeeeettttrrrryyyy    CCCCeeeennnntttteeeerrrr ((((OOOOcccctttt 22222222 1111999999992222))))           lllliiiisssspppp((((3333))))
  71.  
  72.  
  73.  
  74.      DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
  75.       Geomview contains a minimal lisp interpreter for parsing and
  76.       evaluating commands.    This lisp interpreter is part of the
  77.       "-loogutil" library and thus any program which links with
  78.       this library may use the interpreter.     This provides a
  79.       simple but powerful way to build up a    command    language.
  80.  
  81.       This manual page assumes that    you are    familiar with the
  82.       syntax of lisp.  The first part describes the    basics of
  83.       using    the interpreter.  Some gory details that don't concern
  84.       most users then follow.
  85.  
  86.       The main steps in using the lisp interpreter are
  87.  
  88.         1. call Linit() to initialize the interpreter
  89.         2. make calls to LDefun(), one for each lisp function you want the
  90.            interpreter to know about
  91.         3. define the "i/o lake"
  92.         4. parse input with    calls to LSexpr() and evaluate the resulting
  93.            lisp objects with LEval() (or use LEvalSexpr() to combine both steps).
  94.  
  95.       For example the following code defines a single function "f"
  96.       and executes commands    from standard input:
  97.  
  98.           #include "lisp.h"
  99.           Lake *lake;
  100.           LObject *obj, *val;
  101.  
  102.           LInit();
  103.           LDefun("f", f, NULL);
  104.           lake = LakeDefine(stdin, stdout, NULL);
  105.           while (!feof(stdin)) {
  106.         obj = LSexpr(lake);
  107.         val = LEval(obj);
  108.         LFree(obj);
  109.         LFree(val);
  110.           }
  111.  
  112.       The second argument to LDefun() is a function    pointer;
  113.       LDefun() sets    up a correspondence between the    string "f" and
  114.       the function f, which    is assumed to have been    previously
  115.       declared.  The section FUNCTION DEFINITIONS below gives the
  116.       expected call    syntax and behavior of such functions.    (The
  117.       third    argument to LDefun() is    a pointer to a string which
  118.       documents the    function and may be NULL if you    don't care
  119.       about    documentation.)     LakeDefine() defines an i/o lake;
  120.       this is a generalization of the notion of an i/o stream.
  121.       Most programs    don't need to use the generalization, though,
  122.       and can simply pass FILE pointers as LakeDefine()'s first
  123.       two arguments    and NULL as the    third one.  The    section    LAKES
  124.       below    gives the details for those who    are interested.
  125.       LSexpr() [which stands for Lisp Symbolic EXPRession] parses
  126.  
  127.  
  128.  
  129.      Page 2                        (printed 12/22/98)
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.      lllliiiisssspppp((((3333))))           GGGGeeeeoooommmmeeeettttrrrryyyy    CCCCeeeennnntttteeeerrrr ((((OOOOcccctttt 22222222 1111999999992222))))           lllliiiisssspppp((((3333))))
  137.  
  138.  
  139.  
  140.       a single lisp    expression from    the lake, returning a lisp
  141.       object which represents that expression.  The    lisp object is
  142.       returned as an LObject pointer, which    points to an opaque
  143.       structure containing a representation    of the expression.
  144.       LEval() then evaluates the object; it    is during the call to
  145.       LEval() that the action of the expression takes place.  Note
  146.       that the last    two lines of code in this example could    have
  147.       been replaced    by the single line LEval(LSexpr(lake)) or,
  148.       more efficiently, by LEvalSexpr(lake).
  149.  
  150.  
  151.      FFFFUUUUNNNNCCCCTTTTIIIIOOOONNNN DDDDEEEEFFFFIIIINNNNIIIITTTTIIIIOOOONNNNSSSS
  152.       The functions    defined    by calls to LDefun() are expected to
  153.       have a certain call syntax; LEval() calls them when it
  154.       encounters a call to the lisp    function named with the
  155.       corresponding    string.     The macro LDEFINE is provided for
  156.       declaring them.  For example:
  157.  
  158.           LDEFINE(f, LSTRING, "(f a    b) returns a string representing the0um    of the integer a with the floating point number    b.")
  159.           {
  160.         int a;
  161.         float b;
  162.         char buf[20], *s;
  163.  
  164.         LDECLARE(("f", LBEGIN,
  165.               LINT,      &a,
  166.               LFLOAT, &b,
  167.               LEND));
  168.         sprintf(buf,"%f",a+b);
  169.         s = strdup(buf);
  170.         return LNew(LSTRING, &s);
  171.           }
  172.  
  173.       The important    things about this function are:
  174.  
  175.           1. It is declared    with the LDEFINE macro,    the general syntax
  176.          of which is LDEFINE(name, type, helpstr).  name should    be
  177.          a valid C identifer and will be used to construct the actual
  178.          name of the C function    by prepending an 'L' and the name of
  179.          the help string by prepending an 'H'.    type should be a lisp
  180.          object    type identifier    (see below) and    determines the type
  181.          of object that    the function returns.  helpstr is a documentation
  182.          string.
  183.  
  184.           2. The use of the    LDECLARE macro.     More about this below.
  185.  
  186.           3. It returns an LObject *.  All lisp functions must actually
  187.          return    a value.  If you don't care what value they return
  188.          you can return    one of the pre-defined values Lnil or Lt
  189.          (and specify LVOID as the type    in the LDEFINE header).
  190.  
  191.       This particular example is a function    which takes two
  192.  
  193.  
  194.  
  195.      Page 3                        (printed 12/22/98)
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.      lllliiiisssspppp((((3333))))           GGGGeeeeoooommmmeeeettttrrrryyyy    CCCCeeeennnntttteeeerrrr ((((OOOOcccctttt 22222222 1111999999992222))))           lllliiiisssspppp((((3333))))
  203.  
  204.  
  205.  
  206.       arguments, an    int and    a float, and returns a string object
  207.       representing their sum.  A lisp call to this function    might
  208.       look like "(f    1 3.4)".
  209.  
  210.       The LDECLARE macro, defined in lisp.h, sets up the
  211.       correspondence between variables in the C code and arguments
  212.       in the lisp call to the function.  Note that the arguments
  213.       to LDECLARE are delimited by *two* pairs of parentheses
  214.       (this    is because C does not allow macros with    a variable
  215.       number of arguments; LDECLARE    thus actually takes one
  216.       argument which is a parenthesized list of an arbitrary
  217.       number of items).  The general usage of LDECLARE is
  218.  
  219.           LDECLARE(( name, LBEGIN,
  220.              <argspec>,
  221.              ...,
  222.              LEND ));
  223.  
  224.       where    name is    the name of the    function (as specified to
  225.       LDefun()).  <argspec>    is an argument specification, which in
  226.       general consists of a    lisp type identifier followed by an
  227.       address.  The    identifier indicates the data type of the
  228.       argument.  The builtin type identifiers are LINT (integer),
  229.       LFLOAT (float), LSTRING (string), LLOBJECT (lisp object),
  230.       and LLIST (lisp list).  Applications may define additional
  231.       types    whose identifiers may also be used here; see the
  232.       section CUSTOM LISP TYPES below for details.    There may be
  233.       any number of    <argspec>'s; the last must be followed by the
  234.       special keyword LEND.
  235.  
  236.  
  237.      SSSSTTTTOOOOPPPP HHHHEEEERRRREEEE
  238.       Most users of    the lisp interpreter can stop reading this man
  239.       page here.  What follows is only used    in advanced
  240.       situations.
  241.  
  242.  
  243.      EEEEVVVVAAAALLLLUUUUAAAATTTTIIIIOOOONNNN    OOOOFFFF FFFFUUUUNNNNCCCCTTTTIIIIOOOONNNN AAAARRRRGGGGUUUUMMMMEEEENNNNTTTTSSSS
  244.       Normally the lisp interpreter    evaluates function arguments
  245.       before passing them to the function; to prevent this
  246.       evaluation from happening you    can insert the special token
  247.       LHOLD    in an LDECLARE argument    specification before the type
  248.       keyword.  For    example
  249.  
  250.           LHOLD, LLIST, &list,
  251.  
  252.       specifies an unevalutated list argument.  This feature is
  253.       really useful    only for LLIST,    LLOBJECT, and array types (see
  254.       below) since the other types evalutate to themselves.
  255.  
  256.  
  257.      AAAARRRRRRRRAAAAYYYYSSSS
  258.  
  259.  
  260.  
  261.      PPPPaaaaggggeeee 4444                        ((((pppprrrriiiinnnntttteeeedddd 11112222////22222222////99998888))))
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.      lllliiiisssspppp((((3333))))           GGGGeeeeoooommmmeeeettttrrrryyyy    CCCCeeeennnntttteeeerrrr ((((OOOOcccctttt 22222222 1111999999992222))))           lllliiiisssspppp((((3333))))
  269.  
  270.  
  271.  
  272.       In general an    <argspec> in the LDECLARE call consists    of a
  273.       keyword followed by the address of a scalar data type.
  274.       Since    it is relatively common    to use a lisp list to
  275.       represent an array of    values,    however, the special <argspec>
  276.       keyword LARRAY is provided for dealing with them.  It    has a
  277.       different syntax: it should be followed by a lisp type
  278.       identifier which specifies the type of the elements of the
  279.       array    and then by two    addresses --- the address of an    array
  280.       and the address of an    integer    count.    Upon entry to LDECLARE
  281.       the count specifies how many elements    may be written into
  282.       the array.  LDECLARE then modifies this number to indicate
  283.       the number of    entries    actually parsed.  For example:
  284.  
  285.           LDEFINE(myfunc, ...)
  286.           {
  287.         float f[2];
  288.         int fn = 2;
  289.         LDECLARE(("myfunc", LEBGIN
  290.               LHOLD, LARRAY, f, &fn,
  291.               LEND));
  292.         /* at this point the value of fn has been modified to
  293.            be the number of entries actually appearing in the
  294.            list    argument; and this number of values have been
  295.            written into    the array f. */
  296.         ...
  297.           }
  298.  
  299.       defines a function "myfunc" which takes a list of up to 2
  300.       floats as its    only argument.    Valid calls to "myfunc"    would
  301.       be "(myfunc ())", "(myfunc (7))", and    "(myfunc (7 8))".
  302.  
  303.       Note the use of LHOLD; this is necessary because otherwise
  304.       the lisp system would    attempt    to evaluate the    list as    a
  305.       function call    before passing it off to myfunc.
  306.  
  307.  
  308.      OOOOPPPPTTTTIIIIOOOONNNNAAAALLLL AAAARRRRGGGGUUUUMMMMEEEENNNNTTTTSSSS
  309.       Normally the lisp interpreter    will generate (to stderr) a
  310.       reasonable error message if a    function is called with    fewer
  311.       arguments than were specified    in LDECLARE.  Some functions,
  312.       however, may have some arguments that    are optional.  You can
  313.       define a function which takes    optional arguments by putting
  314.       the keyword LOPTIONAL    after the last required    argument in
  315.       the LDECLARE call.  Any arguments specified in the list
  316.       after    that are considered optional; the interpreter doesn't
  317.       complain if they are not supplied.  Note that    all optional
  318.       arguments must come after all    required arguments.
  319.  
  320.       Normally excess arguments also elicit    an error message.  The
  321.       LREST    keyword    allows control over this situation.  If    LREST
  322.       is followed by a pointer to an LList * variable, then
  323.       trailing arguments are parsed, evaluated (unless LHOLD was
  324.  
  325.  
  326.  
  327.      Page 5                        (printed 12/22/98)
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.      lllliiiisssspppp((((3333))))           GGGGeeeeoooommmmeeeettttrrrryyyy    CCCCeeeennnntttteeeerrrr ((((OOOOcccctttt 22222222 1111999999992222))))           lllliiiisssspppp((((3333))))
  335.  
  336.  
  337.  
  338.       used), and the list of them is stored    in the given variable.
  339.       (Note    that the value is an LList, not    an LObject of type
  340.       LLIST    -- if there are    no excess arguments, the value is
  341.       NULL,    not an empty LLIST.)  If LREST is followed by a    NULL
  342.       pointer, excess arguments are    silently ignored.  LREST might
  343.       be useful when a function's argument types are not known.
  344.       It's not necessary to    specify    LEND after LREST.
  345.  
  346.  
  347.      LLLLIIIISSSSPPPP OOOOBBBBJJJJEEEECCCCTTTTSSSS
  348.       The basic data type of the lisp interpreter is the lisp
  349.       object; it is    represented by an LObject pointer, which
  350.       points to an opaque data structure.  The functions for
  351.       manipulating lisp objects (i.e. the object's methods)    are:
  352.  
  353.           LNew(): creates a    new lisp object    of the given type with
  354.           the given value.  The    "type" argument    is one of the
  355.           values LSTRING or LLIST, or a    type pointer defining
  356.           a custom object type (see CUSTOM OBJECT TYPES
  357.           below).
  358.           LRefIncr(): increments the reference count of a lisp
  359.           object.  The lisp interpreter    uses the convention
  360.           that when a procedure    returns    a lisp object, the
  361.           caller owns the object and thus has responsibility
  362.           for freeing it.  LRefIncr() can be used to increment
  363.           the reference    count of an existing object about to
  364.           be returned.    New objects created by LNew() have
  365.           their    reference count    initialized to 1 and hence do
  366.           not need to be LRefIncr()'ed.
  367.           LRefDecr(): decrements the reference count of a lisp
  368.           object.  This    should probably    not be called by
  369.           application programs;    it is used internally.
  370.           LWrite():    writes a formatted string representation of a
  371.           lisp object to a stream.
  372.           LFree(): free the    space assoicated with a    lisp object
  373.           LCopy(): construct a copy    of a lisp object
  374.  
  375.  
  376.      CCCCUUUUSSSSTTTTOOOOMMMM OOOOBBBBJJJJEEEECCCCTTTT TTTTYYYYPPPPEEEESSSS
  377.       In addition to the predefined    lisp object types you may
  378.       define your own custom types.     This is done by constructing
  379.       a structure containing various function pointers for
  380.       manipulating objects of your new type.  The address of this
  381.       structure is then the    type identifier    for this type and may
  382.       be used in LDECLARE <argspec>'s and in LNew()    calls.    (The
  383.       type names LINT, LSTRING and the other builtin types are
  384.       actually pointers to predefined structures.)    The structure
  385.       is of    type LType as defined in lisp.h:
  386.  
  387.       struct LType {
  388.  
  389.         /* name of type */
  390.  
  391.  
  392.  
  393.      Page 6                        (printed 12/22/98)
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.      lllliiiisssspppp((((3333))))           GGGGeeeeoooommmmeeeettttrrrryyyy    CCCCeeeennnntttteeeerrrr ((((OOOOcccctttt 22222222 1111999999992222))))           lllliiiisssspppp((((3333))))
  401.  
  402.  
  403.  
  404.         char *name;
  405.  
  406.         /* size of corresponding C type */
  407.         int    size;
  408.  
  409.         /* extract cell value from obj */
  410.         int    (*fromobj)(/* LObject *obj, void *x */);
  411.  
  412.         /* create a    new LObject of this type */
  413.         LObject *(*toobj)(/* void *x */);
  414.  
  415.         /* free a cell of this type    */
  416.         void (*free)(/* void *x */);
  417.  
  418.         /* write a cell value to a stream */
  419.         void (*write)(/* FILE *fp, void *x */);
  420.  
  421.         /* test equality of    two cells of this type */
  422.         int    (*match)(/* void *a, void *b */);
  423.  
  424.         /* pull a cell value from a    va_list    */
  425.         void (*pull)(/* va_list *a_list, void *x */);
  426.  
  427.         /* parse an    object of this type */
  428.         LObject *(*parse)(/* Lake *lake */);
  429.  
  430.         /* magic number; always set    to LTypeMagic */
  431.         int    magic;
  432.  
  433.       };
  434.  
  435.       The void * pointers in the above point to objects of the
  436.       type you are defining.  For examples of how to define    new
  437.       types    see the    code in    lisp.c that defines the    string and
  438.       list types.  See also    the file TYPES.DOC in the lisp source
  439.       code directory for further details.
  440.  
  441.  
  442.      LLLLIIIISSSSTTTTSSSS
  443.       The LList pointer is used to refer to    objects    of type    LLIST,
  444.       which    implement a linked list.  The operations on these
  445.       objects are LListNew(), LListLength(), LListEntry(),
  446.       LListAppend(), LListCopy(), and LListFree().    These are
  447.       mostly used internally by the    lisp system but    are available
  448.       for outside use.  Maybe I'll write more documentation    for
  449.       them later if    it seems necessary.
  450.  
  451.  
  452.      LLLLAAAAKKKKEEEESSSS TTTThhhheeee LLLLaaaakkkkeeee ssssttttrrrruuuuccccttttuuuurrrreeee iiiissss aaaa
  453.       It contains three members: an    input FILE pointer
  454.       ("streamin"),    an output FILE pointer ("streamout"), and an
  455.       arbitrary pointer ("river").    The input FILE pointer is
  456.  
  457.  
  458.  
  459.      Page 7                        (printed 12/22/98)
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.      lllliiiisssspppp((((3333))))           GGGGeeeeoooommmmeeeettttrrrryyyy    CCCCeeeennnntttteeeerrrr ((((OOOOcccctttt 22222222 1111999999992222))))           lllliiiisssspppp((((3333))))
  467.  
  468.  
  469.  
  470.       required; the    lisp interpreter assumes that every lake has a
  471.       valid    input file pointer.  The output    FILE pointer is
  472.       required if you do any operations that result    in the
  473.       intepreter producing any output.  The    third pointer may
  474.       point    to whatever you    want.  The lisp    interpreter itself
  475.       does not directly refer to this pointer.  It may be used by
  476.       the parser that you supply when defining a new lisp object
  477.       type.
  478.  
  479.       The term "Lake" is supposed to connote something more
  480.       general than a stream; it also seemed    particularly
  481.       appropriate since this interpreter was written in the    City
  482.       of Lakes.
  483.  
  484.  
  485.      HHHHIIIIDDDDDDDDEEEENNNN LLLLAAAAKKKKEEEE AAAARRRRGGGGUUUUMMMMEEEENNNNTTTTSSSS AAAANNNNDDDD OOOOTTTTHHHHEEEERRRR WWWWEEEETTTT
  486.       This section is X rated.  Don't read it unless you are
  487.       really serious.
  488.  
  489.       The lisp interpreter works by    first parsing (LSexpr()) an
  490.       expression then evaluating it    (LEval()).  The    LDECLARE macro
  491.       is a mechanism which allows both the syntax (for parsing)
  492.       and the semantics (for evaluation) of    an expression to be
  493.       specified in the same    convenient place --- at    the top    of the
  494.       C function which implements the function.  The call syntax
  495.       of all such C    functions is
  496.  
  497.           LObject *func(Lake *lake,    LList *args)
  498.  
  499.       When parsing a call to the corresponding lisp    function,
  500.       LSexpr() calls func with that    lake pointer, and with args
  501.       pointing to the head of the list in the parse    tree
  502.       corresponding    to this    function call.    LDECLARE parses    the
  503.       arguments in the call    (by reading them from the lake)    and
  504.       appends them to this list.  (Note: the head of this list is
  505.       the function itself, so the first argument becomes entry #2
  506.       in the list.)
  507.  
  508.       When evaluating the function call, LEval() calls func    with
  509.       lake=NULL and    with args pointing to the call's argument
  510.       list.     (In this case the first entry of the list is the
  511.       first    argument.)  LDECLARE then converts the arguments in
  512.       the list into    the appropriate    C data types, writing their
  513.       values into the addresses in the <argspec>s.
  514.  
  515.  
  516.       One side-effect of using lake=NULL as    the signal to evaluate
  517.       rather than to parse is that the value of the    lake pointer
  518.       is not available at evaluation time.    Some functions,
  519.       however, may want to do something with the lake they were
  520.       parsed from. For example, the    "write"    function in geomview
  521.       writes data to the output stream associated with its input
  522.  
  523.  
  524.  
  525.      Page 8                        (printed 12/22/98)
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.      lllliiiisssspppp((((3333))))           GGGGeeeeoooommmmeeeettttrrrryyyy    CCCCeeeennnntttteeeerrrr ((((OOOOcccctttt 22222222 1111999999992222))))           lllliiiisssspppp((((3333))))
  533.  
  534.  
  535.  
  536.       stream.  (In geomview    these streams are all stored in    a
  537.       general "Pool" structure which is retained as    the "river"
  538.       member of the    lake.)    The special token LLAKE    may be used to
  539.       cause    the lake pointer to be saved in    the args list at parse
  540.       time and written into    a variable at evaluation time.    It is
  541.       used exactly like the    other (scalar) argument    keywords:
  542.  
  543.           LObject *func(Lake *lake,    LList *args)
  544.           Lake *mylake;
  545.           LDECLARE(("myfunc", LBEGIN
  546.             LARG_LAKE, &mylake,
  547.             ...
  548.             LARG_END));
  549.  
  550.       At evaluation    time LDECLARE will set mylake to have the
  551.       value    that lake had at parse time.  This looks just like a
  552.       specification    for an argument    to the lisp function but it is
  553.       not --- it is    just a way to tell LDECLARE to remember    the
  554.       lake pointer between parse- and evaluation-time.
  555.  
  556.  
  557.      BBBBUUUUGGGGSSSS
  558.       The documentation is incomplete.
  559.  
  560.  
  561.      AAAAUUUUTTTTHHHHOOOORRRR
  562.       The lisp interpreter was written mostly by Mark Phillips
  563.       with lots of input and moral support from Stuart Levy    and
  564.       Tamara Munzner.
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.      Page 9                        (printed 12/22/98)
  592.  
  593.  
  594.  
  595.